package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.BrandCategoryMapper;
import cn.tedu.csmall.product.mapper.CategoryMapper;
import cn.tedu.csmall.product.mapper.SpuMapper;
import cn.tedu.csmall.product.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.vo.CategoryListItemVO;
import cn.tedu.csmall.product.pojo.vo.CategoryStandardVO;
import cn.tedu.csmall.product.service.ICategoryService;
import cn.tedu.csmall.product.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class CategoryServiceImpl implements ICategoryService{

    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private BrandCategoryMapper brandCategoryMapper;
    @Autowired
    private SpuMapper spuMapper;

    public CategoryServiceImpl(){
        log.debug("创建业务对象：CategoryServiceImpl");
    }

    @Override
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        int count = categoryMapper.countByName(categoryAddNewDTO.getName());
        if(count > 0){
            String message = "添加类别失败，尝试添加的类别名称已经被使用！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        Category category = new Category();
        BeanUtils.copyProperties(categoryAddNewDTO, category);
        int rows = categoryMapper.insert(category);
        if (rows != 1) {
            String message = "添加管理员失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }
    }

    @Override
    public void delete(Long id) {
        log.debug("开始处理【根据id删除类别】的业务，参数：{}", id);
        //查询数据是否存在
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        if(queryResult == null){
            String message = "删除类别失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        //如果存在“品牌与类别的关联数据”涉及此类别，则不允许删除
        int count = brandCategoryMapper.countByCategoryId(id);
        if(count > 0){
            String message = "删除类别失败，当前类别存在品牌与类别的关联数据！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //如果存在SPU关联到此类别，则不允许删除
        count = spuMapper.countByCategoryId(id);
        if(count > 0){
            String message = "删除类别失败，当前类别存在SPU关联到此类别！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        log.debug("即将执行删除数据，参数：{}", id);
        int rows = categoryMapper.deleteById(id);
        if (rows != 1) {
            String message = "添加管理员失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }
    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id, 1);
    }

    @Override
    public void setDisable(Long id) {
        updateEnableById(id, 0);
    }

    @Override
    public void setDisplay(Long id) {
        updateDisplayById(id, 1);
    }

    @Override
    public void setNoDisplay(Long id) {
        updateDisplayById(id, 0);
    }

    @Override
    public List<CategoryListItemVO> getSubCategoriesByParentId(Long parentId) {
        log.debug("开始处理【根据父级类别id查询子级类别】的业务，父级类别ID：{}", parentId);
        List<CategoryListItemVO> subCategories = categoryMapper.getSubCategoriesByParentId(parentId);
        log.debug("查询完成，子级类别：{}", subCategories);
        return subCategories;
    }

    @Override
    public List<CategoryListItemVO> list() {
        log.debug("开始处理【查询类别列表】的业务，参数：无");
        List<CategoryListItemVO> list = categoryMapper.list();
        return list;
    }

    private void updateEnableById(Long id, Integer enable){
        String[] enableText = {"禁用", "启用"};
        log.debug("开始处理" + enableText[enable] + "类别的业务，类别ID：{}，目标状态：{}", id, enable);
        //查询数据是否存在
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        if(queryResult == null){
            String message = enableText[enable] + "类别失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        //状态是否冲突
        if(queryResult.getEnable().equals(enable)){
            String message = enableText[enable] + "状态失败，该类别已经是" + enableText[enable] + "状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        Category category = new Category();
        category.setId(id);
        category.setEnable(enable);
        int rows = categoryMapper.update(category);
        if (rows != 1) {
            String message = "添加管理员失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    private void updateDisplayById(Long id, Integer isDisplay){
        String[] displayText = {"隐藏", "显示"};
        log.debug("开始处理" + displayText[isDisplay] + "类别的业务，类别ID：{}，目标状态：{}", id, isDisplay);
        //查询数据是否存在
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        if(queryResult == null){
            String message = displayText[isDisplay] + "类别失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        //状态是否冲突
        if(queryResult.getIsDisplay().equals(isDisplay)){
            String message = displayText[isDisplay] + "状态失败，该类别已经是" + displayText[isDisplay] + "状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        Category category = new Category();
        category.setId(id);
        category.setIsDisplay(isDisplay);
        int rows = categoryMapper.update(category);
        if (rows != 1) {
            String message = "添加管理员失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }
}
